home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
comms
/
pipeln10.zip
/
VALVE.C
< prev
next >
Wrap
Text File
|
1990-06-01
|
16KB
|
553 lines
/***************************************************************************
* VALVE vers 1.10, DOS *
* Control program for TSRs PIPELINE and AQUEDUCT *
* 03/06/90 *
* by James W. Birdsall *
* *
* compiles under Turbo C 2.0 *
* *
* This program contains the large-scale control functions for the TSRs *
* PIPELINE and AQUEDUCT, which connect COM1 and COM2 in software. *
* VALVE sets up the COM ports, enables and disables the TSR, and *
* removes it. *
* *
***************************************************************************/
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <bios.h>
#include <ctype.h>
#define INTERFACEINT 0xF1 /* interrupt # of TSR/VALVE interface */
#define INTCONTROLPORT 0x21 /* 8259A interrupt enable mask port */
#define INTENABLE 0x01 /* type of interrupt to enable on UARTs */
#define LINEEMASK 0x0B /* mask: enable UART interrupts, raise lines */
#define LINEDMASK 0xF7 /* mask: disable UART interrupts, leave lines */
/* TO CHANGE FROM COM1 OR COM2, CHANGE THE */
/* FOLLOWING INTERRUPT AND PORT VALUES */
#define DISABLEMASK 0x18 /* mask to enable COM port interrupts */
#define ENABLEMASK 0xE7 /* mask to disable COM port interrupts */
#define COM1INT 0x0C /* interrupt number for COM1 */
#define COM2INT 0x0B /* interrupt number for COM2 */
#define COM1IER 0x3F9 /* Interrupt Enable Register on COM1 */
#define COM1MCR 0x3FC /* Modem Control Register on COM1 */
#define COM2IER 0x2F9 /* Interrupt Enable Register on COM2 */
#define COM2MCR 0x2FC /* Modem Control Register on COM2 */
/* END OF INTERRUPT AND PORT VALUES */
#define ENA 0x1 /* internal flags */
#define DISA 0x0
#define CHAIN 0x1
#define NOCHAIN 0x0
#define USER 0x0
#define INTERNAL 0x1
#define CHAINOFF 0x0
#define CHAINON 0x2
#define AQUEDUCT 'A' /* TSR identifiers */
#define PIPELINE 'P'
#undef inportb
#undef outportb
char copyright[] = "Copyright (c) 1990 James W. Birdsall. All Rights Reserved";
char VERSION[] = "1.10";
/* structure of data within TSR */
typedef struct {
int errors;
void far *B;
void far *oldB;
void far *C;
void far *oldC;
unsigned int PSPseg;
void far *oldinterface;
char enabled;
char chain;
/* the following fields are found only in AQUEDUCT */
int one_in_head, one_in_tail, two_in_head, two_in_tail;
char busyflag;
} paramblock;
/* structure of a DOS Memory Control Block */
typedef struct {
unsigned char type;
unsigned int owner;
unsigned int size;
char junk[11];
} MCB;
void swapvect(paramblock far *, int);
paramblock far *instcheck(void);
void disable_pipe(paramblock far *, int);
void enable_pipe(paramblock far *, int);
int remove_pipe(paramblock far *);
void setup(paramblock far *, int, char *[]);
void usage(void);
char TSRtype; /* stores type of TSR found */
char *TSRname; /* pointer to name of TSR found */
/**************************************************************************
* MAIN *
* Handles argument parsing, etc. *
**************************************************************************/
main(int argc, char *argv[])
{
paramblock far *params;
int temp;
/* check arguments */
if (argc < 1) {
usage();
}
/* check for installation and get far pointer to parameter block */
params = instcheck();
/* act according to first argument */
switch (argv[1][0]) {
/* SETUP */
case 'S':
case 's':
setup(params, argc, argv);
printf("%s set up and enabled OK.\n", TSRname);
break;
/* ENABLE OR ERROR COUNT */
case 'E':
case 'e':
/* ENABLE */
if ((argv[1][1] == 'N') || (argv[1][1] == 'n')) {
temp = USER | ((toupper(argv[2][0]) == 'C') ? CHAINON : CHAINOFF);
enable_pipe(params, temp);
printf("%s enabled.\n", TSRname);
}
/* ERROR COUNT */
else if (toupper(argv[1][1]) == 'R') {
printf("Error count is %d.\n", params->errors);
params->errors = 0;
}
else {
usage();
}
break;
/* DISABLE */
case 'D':
case 'd':
disable_pipe(params, USER);
printf("%s disabled.\n", TSRname);
break;
/* REMOVE */
case 'R':
case 'r':
if (remove_pipe(params)) {
printf("Removal of %s failed\n", TSRname);
}
else {
printf("%s removed OK.\n", TSRname);
}
break;
/* BAD COMMAND */
default:
usage();
break;
}
exit(0);
} /* end of MAIN */
/**************************************************************************
* SETUP *
* Sets up the comm ports. *
**************************************************************************/
void setup(paramblock far *params, int argc, char *argv[])
{
int baud;
unsigned char biosparam = 0x0;
/* check arguments */
if (argc < 4) {
usage();
}
/* get baud */
if ((baud = atoi(argv[2])) == 0) {
usage();
}
switch (baud) {
case 110:
break;
case 150:
biosparam |= 0x20;
break;
case 300:
biosparam |= 0x40;
break;
case 600:
biosparam |= 0x60;
break;
case 1200:
biosparam |= 0x80;
break;
case 2400:
biosparam |= 0xA0;
break;
case 4800:
biosparam |= 0xC0;
break;
case 9600:
biosparam |= 0xE0;
break;
default:
usage();
break;
}
/* get data bits */
switch (argv[3][0]) {
case '7':
biosparam |= 0x02;
break;
case '8':
biosparam |= 0x03;
break;
default:
usage();
break;
}
/* get parity */
switch (argv[3][1]) {
case 'N':
case 'n':
break;
case 'O':
case 'o':
biosparam |= 0x08;
break;
case 'E':
case 'e':
biosparam |= 0x18;
break;
default:
usage();
break;
}
/* get stop bits */
switch (argv[3][2]) {
case '1':
break;
case '2':
biosparam |= 0x04;
break;
default:
usage();
break;
}
/* all arguments verified, so start setup by turning pipeline off */
disable_pipe(params, INTERNAL);
/* set up ports 1 and 2 */
bioscom(0, biosparam, 0);
bioscom(0, biosparam, 1);
/* turn pipeline back on */
enable_pipe(params,
(INTERNAL | ((toupper(argv[4][0]) == 'C') ? CHAINON : CHAINOFF)));
return;
} /* end of SETUP */
/**************************************************************************
* DISABLE_PIPE *
* Disables the TSR. *
**************************************************************************/
void disable_pipe(paramblock far *params, int caller)
{
unsigned char tempbyte;
/* check status */
if ((params->enabled == 0) && ((caller & INTERNAL) != INTERNAL)) {
printf("%s not enabled.\n", TSRname);
exit(0);
}
/* reset enable flag */
params->enabled = 0;
/* disable all types of interrupts at UARTs */
outportb(COM1IER, 0x0);
outportb(COM2IER, 0x0);
/* turn off interrupts at 8259A */
disable();
tempbyte = inportb(INTCONTROLPORT);
tempbyte |= DISABLEMASK;
outportb(INTCONTROLPORT, tempbyte);
enable();
/* reset vectors */
swapvect(params, DISA);
/* turn off interrupts at UARTs */
tempbyte = inportb(COM1MCR);
tempbyte &= LINEDMASK;
outportb(COM1MCR, tempbyte);
tempbyte = inportb(COM2MCR);
tempbyte &= LINEDMASK;
outportb(COM2MCR, tempbyte);
return;
} /* end of DISABLE_PIPE */
/**************************************************************************
* ENABLE_PIPE *
* Enables the TSR. *
**************************************************************************/
void enable_pipe(paramblock far *params, int caller)
{
unsigned char tempbyte;
/* check status */
if ((params->enabled != 0) && ((caller & INTERNAL) != INTERNAL)) {
printf("%s already enabled.\n", TSRname);
exit(0);
}
/* set enable flag */
params->enabled = 1;
/* clear busy flag if AQUEDUCT */
if (TSRtype == AQUEDUCT) {
params->busyflag = 0;
}
/* clear error count */
params->errors = 0;
/* flush buffers if AQUEDUCT */
if (TSRtype == AQUEDUCT) {
params->one_in_head = 0;
params->one_in_tail = 0;
params->two_in_head = 0;
params->two_in_tail = 0;
}
/* set chaining if necessary */
if (caller & CHAINON) {
params->chain = CHAIN;
}
/* disable all types of interrupts at UARTs */
outportb(COM1IER, 0x0);
outportb(COM2IER, 0x0);
/* turn on interrupts at UARTs */
tempbyte = inportb(COM1MCR);
tempbyte |= LINEEMASK;
outportb(COM1MCR, tempbyte);
tempbyte = inportb(COM2MCR);
tempbyte |= LINEEMASK;
outportb(COM2MCR, tempbyte);
/* set vectors */
swapvect(params, ENA);
/* turn on interrupts at 8259A */
disable();
tempbyte = inportb(INTCONTROLPORT);
tempbyte &= ENABLEMASK;
outportb(INTCONTROLPORT, tempbyte);
enable();
/* enable received-available interrupt at UARTs */
outportb(COM1IER, INTENABLE);
outportb(COM2IER, INTENABLE);
return;
} /* end of ENABLE_PIPE */
/**************************************************************************
* SWAPVECT *
* Installs the correct vectors in the interrupt table. *
**************************************************************************/
void swapvect(paramblock far *params, int function)
{
union REGS r;
struct SREGS s;
void far *holderB, far *holderC;
/* enable or disable? */
if (function == ENA) {
holderB = params->B;
holderC = params->C;
}
else if (function == DISA) {
holderB = params->oldB;
holderC = params->oldC;
}
else {
return;
}
/* set COM2 interrupt */
r.h.ah = 0x25;
r.h.al = COM2INT;
s.ds = FP_SEG(holderB);
r.x.dx = FP_OFF(holderB);
intdosx(&r, &r, &s);
/* set COM1 interrupt */
r.h.ah = 0x25;
r.h.al = COM1INT;
s.ds = FP_SEG(holderC);
r.x.dx = FP_OFF(holderC);
intdosx(&r, &r, &s);
return;
} /* end of SWAPVECT */
/**************************************************************************
* REMOVE_PIPE *
* Disables TSR and removes it from memory. *
**************************************************************************/
int remove_pipe(paramblock far *params)
{
union REGS r;
struct SREGS s;
MCB far *temp;
/* disable the pipe */
disable_pipe(params, INTERNAL);
/* restore the old interface vector */
r.h.ah = 0x25;
r.h.al = INTERFACEINT;
s.ds = FP_SEG(params->oldinterface);
r.x.dx = FP_OFF(params->oldinterface);
intdosx(&r, &r, &s);
/* release the memory block occupied by the program manually */
temp = (MCB far *) MK_FP(params->PSPseg - 1, 0x0);
if (temp->type != 0x4D) {
return 1;
}
temp->owner = 0;
return 0;
} /* end of REMOVE_PIPE */
/**************************************************************************
* INSTCHECK *
* Checks for installed TSR and returns type info. *
**************************************************************************/
paramblock far *instcheck(void)
{
union REGS r;
struct SREGS s;
char far *checker;
paramblock far *result;
/* get interrupt vector */
r.h.ah = 0x35;
r.h.al = INTERFACEINT;
intdosx(&r, &r, &s);
checker = (char far *) MK_FP(s.es, r.x.bx);
/* check for signature */
checker -= 6;
if ((*checker != 'J') || (*(checker+1) != 'W') || (*(checker+2) != 'B')) {
printf("Neither AQUEDUCT nor PIPELINE found.\n");
exit(0);
}
/* check for TSR type and version */
checker += 3;
TSRtype = *checker;
switch (*checker) {
case AQUEDUCT:
TSRname = "AQUEDUCT";
break;
case PIPELINE:
TSRname = "PIPELINE";
break;
default:
printf("TSR identifier error!\n");
exit(0);
}
printf("%s vers %c.%c found.\n", TSRname, *(checker+1), *(checker+2));
/* call interrupt to get pointer to parameter block */
int86(INTERFACEINT, &r, &r);
result = (paramblock far *) MK_FP(r.x.ax, r.x.bx);
return result;
} /* end of INSTCHECK */
/**************************************************************************
* USAGE *
* Prints usage message and exits. *
**************************************************************************/
void usage(void)
{
printf("VALVE version %s by James W. Birdsall\n", VERSION);
printf(" for use with the TSRs PIPELINE and AQUEDUCT\n");
printf(" Usage: VALVE Setup baud DPS [Chain]\n");
printf(" ENable\n");
printf(" Disable [Chain]\n");
printf(" ERrors\n");
printf(" Remove\n");
printf(" Only the capital letters in the first argument are significant\n");
printf(" SETUP sets up the communications ports. baud is the baud rate.\n");
printf(" The TSRs support rates of 110, 150, 300, 600, 1200, 2400,\n");
printf(" 4800, and 9600 baud, although rates above 2400 are not\n");
printf(" recommended on slow machines. D is data bits: 7 or 8. P is\n");
printf(" parity: E (even), O (odd), N (none). S is stop bits: 1 or 2.\n");
printf(" Chain allows chaining to previous interrupt vector if serial\n");
printf(" port did not issue the interrupt.\n");
printf(" The TSR is automatically enabled after a setup.\n");
printf(" ENABLE enables PIPELINE or AQUEDUCT. Chain is as in SETUP.\n");
printf(" DISABLE disables PIPELINE or AQUEDUCT\n");
printf(" ERRORS prints out the current error count and clears it.\n");
printf(" REMOVE disables PIPELINE or AQUEDUCT and removes it from memory.\n");
printf("\n");
exit(1);
} /* end of USAGE */